{ Unidad principal

  Copyright (C) 2010 Jorge Turiel <contact>

  This source is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.

  This code is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  details.

  A copy of the GNU General Public License is available on the World Wide Web
  at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  MA 02111-1307, USA.
}
unit uMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  ActnList, SynHighlighterAny,uEditor,uExploraSolucion,uMensajes;

type

  { TfrMain }

  TfrMain = class (TForm )
    acImpotaPlacas: TAction;
    acNuevoProyecto: TAction;
    acGuardarSolucion: TAction;
    acCerrarPestana: TAction;
    acNuevoArchivo: TAction;
    acAbrirArchivo: TAction;
    acAbrirProyecto: TAction;
    acAbrirSolucion: TAction;
    acCompilar :TAction ;
    acOpciones: TAction;
    ActionList1: TActionList;
    Coloreador: TSynAnySyn;
    imgMenus: TImageList;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    mnCompilar :TMenuItem ;
    mnProyecto :TMenuItem ;
    mnGuardarComo: TMenuItem;
    MenuItem7: TMenuItem;
    MenuItem8: TMenuItem;
    MenuItem9: TMenuItem;
    mnCerrarTodos: TMenuItem;
    MenuItem6: TMenuItem;
    mnGuardarSolucion: TMenuItem;
    mnAbrirSolucion: TMenuItem;
    mnCerrar: TMenuItem;
    mnGuardarProyecto: TMenuItem;
    mnAbrirProyecto: TMenuItem;
    mnGuardarArchivo: TMenuItem;
    mnNuevoArchivo: TMenuItem;
    mnNuevoProyecto: TMenuItem;
    mnAbrirFichero: TMenuItem;
    mnNuevo: TMenuItem;
    mnConfiguraPlacas: TMenuItem;
    mnConfigurar: TMenuItem;
    mnPegar: TMenuItem;
    mnCopiar: TMenuItem;
    mnCortar: TMenuItem;
    mnEditar: TMenuItem;
    mnPlacas: TMenuItem;
    mnHerramientas: TMenuItem;
    mnSalir: TMenuItem;
    mnArchivo: TMenuItem;
    procedure acAbrirArchivoExecute(Sender: TObject);
    procedure acAbrirSolucionExecute(Sender: TObject);
    procedure acCerrarPestanaExecute(Sender: TObject);
    procedure acCompilarExecute (Sender :TObject );
    procedure acGuardarSolucionExecute(Sender: TObject);
    procedure acImpotaPlacasExecute (Sender: TObject );
    procedure acNuevoArchivoExecute(Sender: TObject);
    procedure acNuevoProyectoExecute(Sender: TObject);
    procedure acOpcionesExecute(Sender: TObject);
    procedure FormClose (Sender: TObject; var CloseAction: TCloseAction );
    procedure FormCreate (Sender: TObject );
    procedure FormResize (Sender: TObject );
    procedure mnAbrirFicheroClick(Sender: TObject);
    procedure mnAbrirProyectoClick(Sender: TObject);
    procedure mnAbrirSolucionClick(Sender: TObject);
    procedure mnArchivoClick(Sender: TObject);
    procedure mnCompilarClick (Sender :TObject );
    procedure mnConfigurarClick(Sender: TObject);
    procedure mnGuardarArchivoClick(Sender: TObject);
    procedure mnNuevoClick(Sender: TObject);
    procedure mnProyectoClick (Sender :TObject );
    procedure mnSalirClick (Sender: TObject );
  private
    function CreaDirSol(stRuta: String): boolean;
    { private declarations }


  public
    { public declarations }
  frEditor : TfrEditor;
  frExplorador :  TfrExploradorSolucion;

  frMensajes : TFrMensajes;
  end; 

var
  frMain: TfrMain;


implementation

{$R *.lfm}

{ TfrMain }
uses uComun,uAppSettings,uBoards,uCreaProyecto,uSolucion,uEditorComun,
 uControlesComun,uFormPedirArchivo,uUtiles,Compilar, Opciones;


Var
    Configuracion : TConfiguracion;


procedure TfrMain.mnSalirClick (Sender: TObject );
begin
  Close;
end;


procedure TfrMain.FormCreate (Sender: TObject );
begin
  //Posición del formulario principal
  Top := 0;
  Left := 0;
  //Para leer los datos de configuración
  Configuracion := TConfiguracion.Create (true);
  Datos :=Configuracion.MiDirectorio+'Datos'+PathDelim;
  //ListaProyectos := TObjectList.Create (True);
  LimiteSuperior := frMain.Height;
  frMain.WindowState:= wsMaximized;

  NombreSolucion := 'Sin Nombre';

  //Ventana del editor
  frEditor := TfrEditor.Create (self);
  frEditor.Show;

    //Ventana del explorador de solución
    frExplorador := TfrExploradorSolucion.Create(frMain);
    frExplorador.Show;

  //Ventana de mensajes
  frMensajes := TfrMensajes.Create(Self);
  frMensajes.Show;

  dirUsuario := GetAppConfigDir (False);
  If Not (DirectoryExists(DirUsuario)) Then
  Begin
       CreateDir (dirUsuario);
  end;

  DirTEmp := GetTempDir(False)+Application.Title;
  IF Not (DirectoryExists(DirTemp)) Then
   Begin
        CreateDir (DirTemp);
   end;

  //{todo}Quitar despues
   Arduino :='E:\arduino-0018';
  MuestraMensaje (General,'Arduino');
  MuestraMensaje(General,  DirTEmp);

  //Leer puertos serie.
  { TODO -oJorge -cPuerto Serie : Pendiente de probar };
  PuertosSerie := TStringList.Create;
  ListaPuertosSerie (PuertosSerie);
end;

procedure TfrMain.FormResize (Sender: TObject );
begin
  Top := 0;
  Left := 0;
  //frMain.Height := LimiteSuperior;
end;

procedure TfrMain.mnAbrirFicheroClick(Sender: TObject);
begin

end;

procedure TfrMain.mnAbrirProyectoClick(Sender: TObject);
begin

end;

procedure TfrMain.mnAbrirSolucionClick(Sender: TObject);
begin

end;

procedure TfrMain.mnArchivoClick(Sender: TObject);
begin
   mnGuardarSolucion.Enabled:= Solucion <> nil;
   mnGuardarProyecto.Enabled:= Solucion <> nil;
   mnGuardarArchivo.Enabled := Solucion <> nil;
   mnGuardarComo.Enabled:= Solucion <> nil;

   mnAbrirFichero.Enabled := Solucion <> nil;
   mnAbrirProyecto.Enabled := Solucion <> nil;

   mnCerrar.Enabled:= NumeroDeTabs > 0;
   mnCerrarTodos.Enabled:= NumeroDeTabs > 1;
end;

procedure TfrMain .mnCompilarClick (Sender :TObject );
begin

end;

procedure TfrMain.mnConfigurarClick(Sender: TObject);
begin

end;

procedure TfrMain.mnGuardarArchivoClick(Sender: TObject);
begin

  GuardarEditorActual;

end;

procedure TfrMain.mnNuevoClick(Sender: TObject);
begin
  mnNuevoArchivo.Enabled:= Solucion <> nil;
end;

procedure TfrMain .mnProyectoClick (Sender :TObject );
begin
       mnCompilar.Enabled := ProyectoActual <> '' ;
end;

procedure TfrMain.FormClose (Sender: TObject; var CloseAction: TCloseAction );
begin
  //ListaProyectos.Free;
 If Solucion <> Nil Then
 Begin
   Solucion := Nil;
 end;
  //Configuracion.SaveToFile;
  CloseAction := caFree;

end;

procedure TfrMain.acImpotaPlacasExecute (Sender: TObject );
Var
  Placas : TPlacas;
  Destino : String;
  Origen: String;
  boton: LongInt;

begin
   If Arduino = '' Then
   Begin
     ShowMessage ('No encuentro la instalación de Arduino.'+LineEnding+
                 'Comprueba la configuración.');
   Exit;
   end;
   Destino := datos+Boards;
   Origen := Arduino+PathDelim+'hardware'+PathDelim+
             'Arduino'+PathDelim+BoardsArduino;
   IF Not FileExists (Origen) Then
   Begin
     ShowMessage ('No encuentro el fichero: '+BoardsArduino+LineEnding+
                 'En la ruta: '+Origen);
     Exit;
   end;
  Try
  Begin
    boton :=  MessageDlg ('Importar Placas','¿Deseas importar las placas de arduino',
                 mtConfirmation,[mbYes,mbNo],0,mbYes);
    //Todo: Al importar hay que tener en cuenta que no sobraescriba las
    //placas creadas por el usuario.
    //Cuando se esté creada la parte de creación de placas
    If Boton = mrYes Then
    Begin
     Placas := TPlacas.Create;
     Placas.Importar(Origen,Destino);
    end;

  end;
  finally
    Placas.Free;
  end;
end;

procedure TfrMain.acNuevoArchivoExecute(Sender: TObject);
var
  F: TfrPedirNombreArchivo;
  Resultado: LongInt;
  stProyecto: String;
  Fichero : TFichero;
begin
  //Lanzar creador de ficheros

  F := TfrPedirNombreArchivo.Create(frMain);
  Resultado := F.ShowModal;
   stProyecto := F.cbProyectos.Text;
   Fichero.Nombre :=  F.edNombre.Text;
   Fichero.Compilar:= F.chkCompilar.Checked;

  F.Free;

  If Resultado = mrOk Then
  Begin
   Fichero.idTab:= nTabSheet+1;
   IF  (Solucion.AddFicheroAlProyecto (stProyecto,Fichero)) Then
   Begin
      Inc(nTabSheet);
      CrearEditor (Fichero.Nombre,'');
   end
   Else
   Begin
     //Mensaje de Error
     ShowMessage ('El proyecto: '+stProyecto+LineEnding+
                  'Ya tiene un arhivo con el nombre: '+Fichero.Nombre);
   end

  end;
end;

procedure TfrMain.acGuardarSolucionExecute(Sender: TObject);
var
  stRuta: String;
begin
   stRuta := Solucion.Ruta+Solucion.Nombre;
   //stRuta := Solucion.Ruta;
   Solucion.Guardar (stRuta);
end;

procedure TfrMain.acCerrarPestanaExecute(Sender: TObject);
begin
  CerrarPestanaActual;
end;

procedure TfrMain .acCompilarExecute (Sender :TObject );
Var
   I : Integer;

begin
   I:= 0;
   While I < Solucion.Contar do
   Begin
      IF Solucion.Proyectos[i].Nombre = ProyectoActual Then
      Begin
        Try
        CompilarProyecto ( Solucion.Proyectos[i] );
        Except On
          e : Exception DO
          ShowMessage (e.message);
          //exit;
        end;

        Exit;
      end;
      Inc (I);
   end;
end;

{ TODO -oJorge -cAbrir Archivos : Hay que diseñar una manera de indicar si el fichero será compilable o no. }
procedure TfrMain.acAbrirArchivoExecute(Sender: TObject);
Var
  FicheroActual : TFichero;
begin
  With DataModule1 do
  Begin
    If DlgAbrir.Execute Then
    Begin
       //Comprobar que no hay fichero con el mismo nombre en el proyecto
       //Actual
       FicheroActual.Nombre:=ExtraerExtension (DlgAbrir.FileName);
       FicheroActual.Compilar:= True;
       FicheroActual.idTab:= nTabSheet;
       If Solucion.AddFicheroAlProyecto(ProyectoActual,FicheroActual) Then
       Begin
        CrearEditor (FicheroActual.Nombre,DlgAbrir.FileName);
       end
       Else
       Begin
         ShowMessage ('El proyecto: '+ProyectoActual+LineEnding+
                      'Ya tiene un fichero con el nombre: '+FicheroActual.Nombre);
       end;

    end;
  end;
end;

procedure TfrMain.acAbrirSolucionExecute(Sender: TObject);
var
  Resultado: LongInt;
  SolucionACargar: String;
begin
  With DataModule1 do
  Begin
    IF Not (dlgAbrir.Execute) Then Exit;
    SolucionACargar := dlgAbrir.FileName;
  end;
  //Preguntar si se borra la solucion actual
  { TODO -oJorge -cSolucion : Modificar para que solo pregunte cuando la solución esté modificada }
  If (Solucion <> nil)  Then
  Begin
    Resultado :=  MessageDlg ('Atención','Ya existe una solución cargada.'+LineEnding+
                   '¿Deseas guardar la solución actual',mtWarning,[mbYes,mbNo,mbCancel],0,mbYes);
    {
       Boton := MessageDlg ('Atención','Ya ha una solucion creada'+LineEnding+
                          'Deseas continuar creando una solución nueva',mtWarning,
                  [mbYes,mbNo],0,mbNo);    }
    If Resultado = mrCancel Then
    Begin
      Exit;
    end;
    If Resultado = mrYes Then
    Begin
      acGuardarSolucion.Execute;// (Tobject);
    end;
  end;
   //Cargar Solucion
   If Solucion <> nil Then
   Begin
     Solucion.Free;
     Solucion := Nil;
   end;
   Solucion := TSolucion.Create(SolucionACargar);
   ActualizaExplorador;
end;

procedure TfrMain.acNuevoProyectoExecute(Sender: TObject);
var
  frCreaProyecto: TfrCrearProyecto;
  Respuesta: LongInt;
  NombrePlaca: String;
  Proyecto : TProyecto;
  stSolucion: String;
  bNuevaSolucion: Boolean;
  Boton: LongInt;
  RutaSolucion: String;

begin
Try
  frCreaProyecto := TfrCrearProyecto.Create(frMain);
  //Sino hay ningún proyecto se crea uno
  If Solucion = nil Then
  Begin
    frCreaProyecto.chbxSolucionNueva.Checked:=True;
    frCreaProyecto.chbxSolucionNueva.Enabled:=False;
  end
  Else
  Begin
     frCreaProyecto.EditSolucion.Text:=Solucion.Nombre;
     frCreaProyecto.EditSolucion.Enabled:=False;
  end;
  frCreaProyecto.EditDirectorio.Text:=dirUsuario;
  Respuesta := frCreaProyecto.ShowModal;
  // El 1 es OK
  If Respuesta = 1 Then
  Begin
    NombrePlaca := frCreaProyecto.PlacaElegida;
    bNuevaSolucion := frCreaProyecto.bSolucionNueva;
    stSolucion := frCreaProyecto.EditSolucion.Text;
    RutaSolucion :=frCreaProyecto.EditDirectorio.Text+stSolucion+PathDelim;
   { TODO -oJorge -cSolucion : Añadir la opción de guardar el proyecto si este no ha sido guardado }
    If (Solucion <> Nil) and (bNuevaSolucion = true) Then
    Begin
      Boton := MessageDlg ('Atención','Ya ha una solucion creada'+LineEnding+
                          'Deseas continuar creando una solución nueva',mtWarning,
                  [mbYes,mbNo],0,mbNo);


      If Boton = mrNo Then
      Begin
        Exit;
      end
      Else
      Begin
        Solucion := Nil;
        CerrarTabs;
      end;
    end;
    If Solucion = nil Then  //Sino hay ningun dato en la solución
    Begin
      IF Not (CreaDirSol (RutaSolucion)) Then Exit;
      nTabSheet := 1;
      Proyecto := TProyecto.Create(frCreaProyecto.EditNombre.Text,
                                   Main,nTabSheet);

      Proyecto.Ruta := RutaSolucion
                      +Proyecto.Nombre+PathDelim;

      Proyecto.Placa:=NombrePlaca;

      Solucion := TSolucion.Create(Proyecto);
      Solucion.Nombre:=stSolucion;
      Solucion.Ruta:=RutaSolucion;
      ProyectoActual := Proyecto.Nombre;
      CrearEditor (Main,'');
      //Crear Directorio Solución


    end
    Else
    Begin
        //Comprobar si existe el proyecto antes de añadirlo
        If Solucion.ExisteProyecto(frCreaProyecto.EditNombre.Text) = True Then
        Begin
          ShowMessage ('Ya existe un proyecto con el nombre: '+LineEnding+
                       frCreaProyecto.EditNombre.Text+LineEnding+
                       'Por favor selecciona otro nombre para el proyecto');
          Exit;
        end;
        Inc(nTabSheet);
        Proyecto := TProyecto.Create(frCreaProyecto.EditNombre.Text,'Main',
                                     RutaSolucion+ frCreaProyecto.EditNombre.Text+
                                     PathDelim,nTabSheet);
        Proyecto.Ruta := RutaSolucion
                      +Proyecto.Nombre+PathDelim;
        Solucion.AddProyecto(Proyecto);
        CrearEditor (Main,'');
    end;
  end;

 finally
   If Proyecto <> Nil Then
      Proyecto := Nil;
  IF frCreaProyecto <> Nil Then
    frCreaProyecto := Nil;
 end;
end;

procedure TfrMain.acOpcionesExecute(Sender: TObject);
var
  F: TOpcionesForm;
  Resultado: Integer;
begin
  F := TOpcionesForm.Create(Self);
  Try
   Resultado := F.ShowModal;
  finally
   F.Free;
  end;

end;

function TfrMain.CreaDirSol(stRuta: String): boolean;
var
  Boton: LongInt;
  Resultado: Boolean;
begin
   If stRuta = '' Then exit;
   If Not (DirectoryExistsUtf8 (stRuta))Then
   Begin
     CreateDir (stRuta);
     Result := True;
   end
   Else
   Begin
     Boton := MessageDlg ('Atención','Ya existe una solución con este nombre en el disco duro'+
                          LineEnding+'¿Deseas sobreescribirla?'+LineEnding+
                          'Se borraran los datos del disco duro',mtWarning,
                  [mbYes,mbNo],0,mbNo);
     If Boton = mrNo Then
     Begin
       Result := False;
     end
     Else
     Begin
       //Borrar el direcotrio de la solución y todo su contenido
       Resultado := DeleteDirectory (stRuta,True);
       If Resultado = True Then
       Begin
          Resultado := RemoveDirUTF8 (stRuta);
          CreateDir (stRuta);
       end;
       Result := Resultado;
     end;
   end;
end;



end.

